using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Awaken.CodeGen.Entities;
using Awaken.CodeGen.Controls;
using Schemata.Core;

namespace Awaken.CodeGen.Controls
{
    public partial class ProjectControl : System.Web.UI.UserControl
    {
        public string ProjectID
        {
            get 
            {
                return Request.Params["ProjectID"].ToString();
            }
        }

        public Project Project
        {
            get 
            {
                Guid projectID = new Guid(ProjectID);
                return Project.Broker.GetByID(projectID);
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!Page.IsPostBack)
            {
                LoadProject();
            }
        }

        protected void LoadProject()
        {
            this.projectNameTextBox.Text = Project.ProjectName;
            this.classDirectoryTextBox.Text = Project.ClassDirectory;
            this.mappingDirectoryTextBox.Text = Project.MappingDirectory;
            this.testDirectoryTextBox.Text = Project.TestDirectory;
            this.namespaceTextBox.Text = Project.Namespace;
            this.assemblyTextBox.Text = Project.Assembly;
            this.connectionStringTextBox.Text = Project.ConnectionString;
            this.databaseNameTextBox.Text = Project.DatabaseName;
        }

        protected void SaveProject()
        {
            Project.ProjectName = projectNameTextBox.Text.Trim();
            Project.ClassDirectory = classDirectoryTextBox.Text.Trim();
            Project.MappingDirectory = mappingDirectoryTextBox.Text.Trim();
            Project.TestDirectory = testDirectoryTextBox.Text.Trim();
            Project.Namespace = namespaceTextBox.Text.Trim();
            Project.Assembly = assemblyTextBox.Text.Trim();
            Project.ConnectionString = connectionStringTextBox.Text.Trim();
            Project.DatabaseName = databaseNameTextBox.Text.Trim();
            Project.Save();
        }

        public Database Database
        {
            get
            {
                SqlServerSchemaProvider sqlProvider = new SqlServerSchemaProvider();
                DatabaseSchema databaseSchema = new DatabaseSchema(Project.DatabaseName,sqlProvider, Project.ConnectionString );

                Database database = new Database(databaseSchema);
                return database;
            }
        }

        protected void WriteFile(string path, string file, string content)
        {
            string fullPath = path + file;

            FileInfo fi = new FileInfo(fullPath);

            StreamWriter sw = fi.CreateText();
            HtmlTextWriter hw = new HtmlTextWriter(sw);
            sw.Write(content);
            sw.Close();

            informLabel.Text += string.Format("Generated: {0}<br>", fullPath);
        }

        public Table SelectedTable
        {
            get { return Database.SingleIdTables[grid.SelectedIndex]; }
        }

        public string GetRequestString(string url)
        {
            string result = string.Empty;

            try
            {
                WebRequest request = HttpWebRequest.Create(url);
                WebResponse response = request.GetResponse();
                Stream stream = response.GetResponseStream();
                StreamReader reader = new StreamReader(stream);

                result = reader.ReadToEnd();

                response.Close();
                stream.Close();
                reader.Close();
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Error loading page. url=" + url, ex);
            }


            return result;
        }

        public string GetTableBasedContent(string pageUrl)
        {
            StringBuilder url = new StringBuilder();
            url.Append(pageUrl + "?n=0");
            url.AppendFormat("&ConnectionString={0}", Project.ConnectionString);
            url.AppendFormat("&TableName={0}", SelectedTable.TableName);
            url.AppendFormat("&Namespace={0}", Project.Namespace);
            url.AppendFormat("&Assembly={0}", Project.Assembly);
            url.AppendFormat("&DatabaseName={0}", Project.DatabaseName);

            return GetRequestString(url.ToString());
        }

        public string GetSelectedTableClassBody()
        {
            return GetTableBasedContent("http://localhost/Awaken.CodeGen/Class.aspx");
        }

        public string GetSelectedTableMappingBody()
        {
            return GetTableBasedContent("http://localhost/Awaken.CodeGen/Mapping.aspx");
        }

        public string GetSelectedTableTestBody()
        {
            return GetTableBasedContent("http://localhost/Awaken.CodeGen/Test.aspx");
        }

        public void GenerateClass()
        {
            WriteFile(Project.ClassDirectory, SelectedTable.ClassName + "_Gen.cs", GetSelectedTableClassBody());
        }

        public void GenerateMapping()
        {
            WriteFile(Project.MappingDirectory, SelectedTable.ClassName + ".hbm.xml", GetSelectedTableMappingBody());
        }

        public void GenerateTest()
        {
            WriteFile(Project.TestDirectory, SelectedTable.ClassName + "GeneratedFixture.cs", GetSelectedTableTestBody());
        }

        public void saveButton_OnClick(object s, System.EventArgs e)
        {
            SaveProject();
        }

        protected void loadButton_OnClick(object s, System.EventArgs e)
        {
            informLabel.Text = string.Format("SingleIdTables: {0}<br>", Database.SingleIdTables.Count);
            grid.DataSource = Database.SingleIdTables;
            grid.DataBind();

            tablePanel.Visible = true;
        }

        public void allButton_OnClick(object s, System.EventArgs e)
        {
            int initial = grid.SelectedIndex;

            foreach (GridViewRow row in grid.Rows)
            {
                grid.SelectedIndex = row.RowIndex;
                GenerateClass();
                GenerateMapping();
                GenerateTest();
            }
            grid.SelectedIndex = initial;
        }
        
        protected void grid_OnRowCommand(object s, System.Web.UI.WebControls.GridViewCommandEventArgs e)
        {
            grid.SelectedIndex = int.Parse(e.CommandArgument.ToString());

            switch (e.CommandName)
            {
                case ("PreviewClass"): preview.InnerText = GetSelectedTableClassBody(); break;
                case ("GenerateClass"): GenerateClass(); break;

                case ("PreviewMapping"): preview.InnerText = GetSelectedTableMappingBody(); break;
                case ("GenerateMapping"): GenerateMapping(); break;

                case ("PreviewTest"): preview.InnerText = GetSelectedTableTestBody(); break;
                case ("GenerateTest"): GenerateTest(); break;

                default: throw new ArgumentException("Unknown command " + e.CommandName);
            }
        }
    }
}